//
//  CJCommon.swift
//  CJPack
//
//  Created by 陈警卫 on 2022/12/15.
//

import UIKit
import Foundation

public class CJCommon: NSObject {
    
    /// 退出程序
    @objc public static func exit() { 
        if let window = CJScreen.window {
            UIView.animate(withDuration: 0.5) {
                window.alpha = 0
            } completion: { finish in
                _stdlib.exit(0)
            }
        } else {
            _stdlib.exit(0)
        }
    }
    
    /// Any转String
    public static func toString(_ data: Any) -> String {
        if let value = data as? Int {
            return String(value)
        } else if let value = data as? Float {
            return String(value)
        } else if let value = data as? Double {
            return String(value)
        } else if let value = data as? Bool {
            return value ? "true" : "false"
        } else if let value = data as? String {
            return value
        } else {
            return String(describing: data)
        }
    }
}

public extension CJCommon {

    /// 跳转Url
    @objc static func openUrl(_ url: URL, complete: @escaping ((Bool) -> Void)) {
        var comp: Bool = false
        comp = UIApplication.shared.canOpenURL(url)
        if comp {
            UIApplication.shared.open(url,options: [:], completionHandler: { comp in
                complete(comp)
            })
        } else {
            complete(comp)
        }
    }
    
    /// 跳转设置
    @objc static func openSet() {
        guard let url = URL(string: "App-Prefs:Settings") else { return }
        openUrl(url) { comp in
        }
    }
    
    /// 跳转App设置
    @objc static func openSetApp() {
        guard let url = URL(string: UIApplication.openSettingsURLString) else { return }
        openUrl(url) { comp in
        }
    }
}

public extension CJCommon {
    
    /// 获取变量内存地址
    static func addressUnsafe(o: UnsafeRawPointer) -> String {
        return String.init(format: "%018p", Int(bitPattern: o))
    }
    
    /// 获取变量内存地址
    static func addressUnsafe<T: AnyObject>(o: T) -> String {
        let res = String.init(format: "%018p", unsafeBitCast(o, to: Int.self))
        return res
    }
    
    /// 打印对象所有变量名与值
    /// - object: 打印的Any对象
    /// - hasSuper: 是否获取父类的变量 默认 true
    /// - hasAddress: 是否打印class变量的内存地址 默认 true
    /// - return 返回打印信息
    @discardableResult
    static func descriptionAllIvars(_ any: Any?, _ hasSuper:Bool = true, _ hasAddress:Bool = true) -> String {
        var res = ""
        if let model = any {
            let mirror = Mirror(reflecting: model)

            var tagName = "\n<\(type(of: model))>"
            if hasAddress == true {
                if mirror.displayStyle == Mirror.DisplayStyle.class {
                    tagName = "<\(type(of: model)):\(CJCommon.addressUnsafe(o: model as AnyObject))>"
                }
            }
            res += tagName + "\n"

            mirror.children.forEach { (child) in
                if let porperty = child.label {
                    res += "    \(porperty): \(child.value)\n"
                }
            }

            if hasSuper == true {
                var superMirror = mirror.superclassMirror
                while superMirror != nil {
                    superMirror?.children.forEach { (child) in
                        if let porperty = child.label{
                            res += "    \(porperty): \(child.value)\n"
                        }
                    }
                    superMirror = superMirror?.superclassMirror
                }
            }
            res = res.trimmingCharacters(in: .newlines)
            res += tagName
        } else {
            res += "nil"
        }
        return res
    }
}
